package com.mls.fivedistrict.server.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.dao.PropertyMapper;
import com.mls.fivedistrict.enums.AuthStatusEnum;
import com.mls.fivedistrict.enums.RecordChangeReason;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.*;
import com.mls.fivedistrict.server.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static java.math.BigDecimal.ROUND_DOWN;

/**
 * Created by nanji on 2018/3/16.
 */
@Service("propertyService")
public class PropertyServiceImpl implements PropertyService {
    @Resource(name = "propertyMapper")
    private PropertyMapper propertyMapper;

    @Resource(name = "recordService")
    private RecordService recordService;

    @Resource(name = "orePoolService")
    private OrePoolService orePoolService;

    @Resource(name = "integralService")
    private IntegralService integralService;
    @Resource(name = "receiveRecordService")
    private ReceiveRecordService receiveRecordService;


    @Override
    public Property getProperty(Long id, Long userId) {
        Property property = propertyMapper.selectByPrimaryKey(id);
        return property;

    }

    @Override
    public ServiceResponse getPropertyByIntegral(Long integralId, Long userId) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andIntegralIdEqualTo(integralId);
//        propertyExample.setOrderByClause("update_date desc");
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        if (properties.size() > 0) {
            return ServiceResponse.createSuccessResponse(properties.get(0));
        }
        return ServiceResponse.createErrorResponse("资产不存在");
    }

    @Override
    public ServiceResponse getDetailByFilter(Map filter) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        Optional.ofNullable(filter.get("userId")).map(userId -> criteria.andIdEqualTo((Long) userId));
        Optional.ofNullable(filter.get("integralId")).map(integralId -> criteria.andIntegralIdEqualTo((Long) integralId));
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        if (properties.size() == 0) {
            return ServiceResponse.createErrorResponse("不存在");
        }
        return ServiceResponse.createSuccessResponse(properties.get(0));
    }

    @Override
    public ServiceResponse getProperties(PageFilter pageFilter) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        Optional.ofNullable(pageFilter.getFilterMap().get("userId")).map(userId -> criteria.andUserIdEqualTo(Long.valueOf(userId)));
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        for (Property property : properties) {
            property.setTotal(property.getTotal().setScale(4, RoundingMode.DOWN));
        }
        PageInfo pageInfo = new PageInfo(properties, 5);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }


    @Override
    public boolean addProperty(Property property) {
        int row = propertyMapper.insertSelective(property);
        if (row > 0) {
            return true;
        }
        return false;
    }

    @Override
    public ServiceResponse editProperty(Property property) {
        int row = propertyMapper.updateByPrimaryKeySelective(property);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse("修改成功!");
        }
        return ServiceResponse.createErrorResponse("修改失败");
    }

    @Override
    public Property getPropertyDetail(Long id) {
        Property property = propertyMapper.selectByPrimaryKey(id);

        return property;

    }

    @Override
    public Property getPropertyDetailByIntegral(Long integralId, Long userId) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andIntegralIdEqualTo(integralId);
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        if (properties.size() > 0) {
            return properties.get(0);
        }
        return null;
    }

    @Override
    public ServiceResponse insertProperty(Property property) {
        int row = propertyMapper.insertSelective(property);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse();
        }
        return ServiceResponse.createErrorResponse();
    }

    @Override
    public int deleteUserProperty(Long userId, String sourceStatus) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andIsDeleteEqualTo(false);
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        //将积分回收至矿池 同时标记删除
        for (Property property : properties) {
            Property newProperty = new Property();
            newProperty.setTotal(new BigDecimal(0));
            newProperty.setId(property.getId());
            propertyMapper.updateByPrimaryKeySelective(newProperty);
        }
        //删除用户所有记录
        List<Integral> integralList = integralService.getIntegralList();
        for (Integral integral : integralList) {
            //查询出用户次积分下关联的所有记录
            List<Record> recordList = recordService.getRecordList(integral.getId(), userId);
            if (recordList.size() > 0) {
                //积分总和
                BigDecimal recordSum = new BigDecimal(0);
                for (Record record : recordList) {
                    if (sourceStatus.equals(AuthStatusEnum.LOGOUT.getValue())) {
                        record.setChangeReason(RecordChangeReason.LOGOUT.getDesc());
                    } else if (sourceStatus.equals(AuthStatusEnum.REJECT.getValue())) {
                        record.setChangeReason(RecordChangeReason.REJECT.getDesc());
                    }
                    recordSum = recordSum.add(record.getValue()).setScale(8, ROUND_DOWN);
                }
                //将记录包含的积分回收至积分
                Integral integralDetail = integralService.getIntegralDetail(integral.getId());
                Integral newIntegral = new Integral();
                newIntegral.setResidueIntegral(integralDetail.getResidueIntegral().add(recordSum).setScale(8, ROUND_DOWN));
                newIntegral.setId(integralDetail.getId());
                integralService.editIntegral(newIntegral);
                recordService.deleteBatch(recordList);


            }
            //查询记录历史表
            Map params = new HashMap();
            params.put("integralId", integral.getId());
            params.put("userId", userId);
            List<Record> receiveRecordList = receiveRecordService.getReceiveRecordList(params);
            if (receiveRecordList.size() > 0) {
                //积分总和
                BigDecimal recordSum = new BigDecimal(0);
                for (Record record : receiveRecordList) {
                    if (sourceStatus.equals(AuthStatusEnum.LOGOUT.getValue())) {
                        record.setChangeReason(RecordChangeReason.LOGOUT.getDesc());
                    } else if (sourceStatus.equals(AuthStatusEnum.REJECT.getValue())) {
                        record.setChangeReason(RecordChangeReason.REJECT.getDesc());
                    }
                    recordSum = recordSum.add(record.getValue()).setScale(8, ROUND_DOWN);
                }
                //将记录包含的积分回收至积分
                Integral integralDetail = integralService.getIntegralDetail(integral.getId());
                Integral newIntegral = new Integral();
                newIntegral.setResidueIntegral(integralDetail.getResidueIntegral().add(recordSum).setScale(8, ROUND_DOWN));
                newIntegral.setId(integralDetail.getId());
                integralService.editIntegral(newIntegral);
                receiveRecordService.deleteBatch(receiveRecordList);


            }

        }


        return 1;
    }

    @Override
    public BigDecimal getDwqTotal() {
        BigDecimal dwqSum = propertyMapper.getDwqSum(18L);
        return dwqSum;
    }

    @Override
    public List<Property> getPropertiesByIntegral(Long intergral) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        criteria.andIntegralIdEqualTo(intergral);
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        return properties;
    }

    @Override
    public List<Property> getPropertiesByUserId(PageFilter pageFilter, Long userId) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        return properties;
    }

    @Override
    public void addPropertyBashByParadrop(List<ParadropProperty> insertPropertyList) {
        propertyMapper.insertBashByParadrop(insertPropertyList);
    }

    @Override
    public List<Long> getUserIds(Long integralId) {
        List<Long> userIds = propertyMapper.getUserIds(integralId);
        return userIds;
    }

    @Override
    public int updatePropertyBashByParadrop(List<ParadropProperty> updatePropertyList) {
        return propertyMapper.updatePropertyBashByParadrop(updatePropertyList);
    }

    @Override
    public int editPropertyByRecord(Long id, BigDecimal recordValue) {
        Map map = new HashMap();
        map.put("id", id);
        map.put("recordValue", recordValue);
        int i = propertyMapper.editPropertyByRecord(map);
        return i;
    }

    @Override
    public int reducePropertyTotal(Long userId, Long integralId, BigDecimal value) {
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("integralId", integralId);
        map.put("value", value);
        return propertyMapper.reducePropertyTotal(map);
    }

    @Override
    public int increatementPropertyTotal(Long userId, Long integralId, BigDecimal value) {
        Map map = new HashMap();
        map.put("userId", userId);
        map.put("integralId", integralId);
        map.put("value", value);
        return propertyMapper.increamentPropertyTotal(map);
    }

    @Override
    public Property getDWQDetail(Long userId) {
        PropertyExample propertyExample = new PropertyExample();
        PropertyExample.Criteria criteria = propertyExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andIntegralIdEqualTo(18L);
        List<Property> properties = propertyMapper.selectByExample(propertyExample);
        if (properties.size() > 0) {
            Property property = properties.get(0);
            property.setTotal(property.getTotal().setScale(4, ROUND_DOWN));
            return properties.get(0);
        }
        return null;
    }

    @Override
    public Long addPropertyByIntegral(long integralId, BigDecimal integralValue, Long userId) {
        //查看用户是否存在此资产
        Property propertyDetail = getPropertyDetailByIntegral(integralId, userId);
        if (propertyDetail == null) {
            //创建
            Property property = new Property();
            property.setTotal(integralValue);
            property.setUserId(userId);
            property.setIntegralId(integralId);
            boolean b = addProperty(property);
            if (!b) {
                throw new CustomerException("添加资产出错");
            }
            return property.getId();
        } else {
            //累加
            Property property = new Property();
            property.setTotal(propertyDetail.getTotal().add(integralValue).setScale(8, ROUND_DOWN));
            property.setVersion(propertyDetail.getVersion());
            PropertyExample propertyExample = new PropertyExample();
            PropertyExample.Criteria criteria = propertyExample.createCriteria();
            criteria.andVersionEqualTo(propertyDetail.getVersion());
            criteria.andIdEqualTo(propertyDetail.getId());
            int i = propertyMapper.updateByExampleSelective(property, propertyExample);
            if (i <= 0) {
                throw new CustomerException("更新资产出错");
            }
            return propertyDetail.getId();
        }

    }


}
